using System;
using System.Collections.Specialized;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.ComponentModel;
using System.Collections;
using log4net;
using Sedna.Core.Controller.Configurations;
using Sedna.Core.Controls.Support;
using Sedna.Core.Controller;
using Sedna.Core.Controls.Support.Javascript;
using Sedna.Core.DataBinding;
using Sedna.Core.Tiles.Contents;
using DataBinder=Sedna.Core.DataBinding.DataBinder;

namespace Sedna.Core.Controls
{
	public class TextBox : System.Web.UI.WebControls.TextBox, IContent, IConfigurationAware, IClientScriptingControl, IControlDataLoadAware, IValueProvider
	{
        private ILog log = LogManager.GetLogger(typeof(TextBox));
	    
		private IConfiguration configuration;
		protected IDataBinder binder;

		private string configurationId = "configuration.default.TextBox";
		private bool clientScriptingEnabled=false;
		private string clientVariable=null;
        private string javascriptClass;
        private string toolTipKey;


		private String contentPlaceHolderId;

		public String ContentPlaceHolderId
		{
			get { return contentPlaceHolderId;}
			set { contentPlaceHolderId = value;}
		}

		public IConfiguration Configuration
		{
			get { return configuration; }
			set { this.configuration = value; }
		}

		[Bindable(true), Category("Sedna"), DefaultValue("configuration.default.TextBox")]
		public string ConfigurationId
		{
			get { return configurationId; }
			set { this.configurationId = value; }
		}

	    public object Value
	    {
	        get { return Text; }
	        set { Text = value!=null?value.ToString():null; }
	    }

	    #region Javascript support
	    
	    public bool ClientScriptingEnabled
	    {
            get { return clientScriptingEnabled /*|| clientVariable != null*/; }
	        set { clientScriptingEnabled = value; }
	    }

	    public string ClientVariable
	    {
            get { return /*clientVariable*/ ControlUtil.GetClientVariable(this, clientVariable); }
	        set { clientVariable = value; }
	    }

        public string JavascriptClass
        {
            get { return javascriptClass; }
            set { javascriptClass = value; }
        }

        public string NodeName
        {
            get { return ClientID; }
        }

        public virtual string ToolTipKey
        {
            get { return toolTipKey; }
            set { toolTipKey = value; }
        }

        public string LocalizedToolTip
        {
            get
            {
                if (Configuration.DataTranslator != null && Configuration.DataTranslator.GetType() != typeof(TrivialDataTranslator))
                {
                    return ToolTip;
                }
                return Configuration.GetLocalizedPostfixLabel(ToolTipKey, ToolTip);
            }
        }

	    
        private void RenderScriptAttributes(HtmlTextWriter writer)
        {
            foreach (DictionaryEntry entry in BuildScriptParameters())
            {
                writer.AddAttribute("sedna:" + (string)entry.Key, (string)entry.Value);
            }
        }

        private void DeclareScriptVariable()
        {
            ControlUtil.EnsureIdAttribute(this);
            JavascriptController.Current.DeclareClass(JavascriptClass);
            if (ClientVariable != null)
            {
                JavascriptController.Current.DeclareObjectByNode(ClientVariable, JavascriptClass, NodeName);
            }
        }

        protected virtual IDictionary BuildScriptParameters()
        {
            IDictionary parameters = new ListDictionary();
            parameters.Add("jsClass", JavascriptClass);
            parameters.Add("id", ClientID);
            parameters.Add("submitState", Text);
            return parameters;
        }

        #endregion

		public TextBox() :base()
		{
		    //TODO: refactor
            javascriptClass = "TextBox";
			CssClass = "inputsmall";
			Width=Unit.Pixel(120);
		}

		public TextBox(IConfiguration configuration): this()
		{
			Configuration=configuration;
			ConfigurationId=configuration.ObjectName;

            Build();
		}

		public TextBox(string id) :this()
		{
			this.ID = id;
		}

		protected override void OnInit(EventArgs e)
		{
			if (configuration == null)
			{
				configuration = (IConfiguration)SpringContextFactory.GetContext().GetObject(configurationId);
                Build();
			}
            
			binder = new DataBinder(this, configuration, ExecutionContext.GetCurrent(ClientID));
			ControlUtil.SetupClientAttributes(this, configuration);
			base.OnInit (e);
		}

        protected void Build()
		{
            if (configuration == null)
                return;
            
			ID=configuration.Id;
			Width=configuration.Width;
			Height=configuration.Height;
		    		    		    
			Enabled = configuration.IsEnabledForPrincipal() && configuration.Enabled;
			Visible = configuration.IsVisibleForPrincipal() && configuration.Visible;

			ITextBoxConfiguration textBoxConfiguration = configuration as ITextBoxConfiguration;
			if (textBoxConfiguration == null)
			{
				return;
			}
/*
			if (textBoxConfiguration.TextBoxMode != null && !string.Empty.Equals(textBoxConfiguration.TextBoxMode))
			{
				this.TextMode = (TextBoxMode) Enum.Parse(typeof(TextBoxMode), textBoxConfiguration.TextBoxMode);
			}
*/

			this.Columns = textBoxConfiguration.Columns;
			this.Rows = textBoxConfiguration.Rows;
			this.MaxLength=textBoxConfiguration.MaxLength;
            this.ReadOnly = textBoxConfiguration.ReadOnly;
            this.BorderStyle = textBoxConfiguration.BorderStyle;
            this.Wrap = textBoxConfiguration.Wrap;


            TextMode = textBoxConfiguration.TextBoxMode;
            
            
			ClientScriptingEnabled=textBoxConfiguration.ClientScriptingEnabled;
			ClientVariable=textBoxConfiguration.ClientVariable;             
		}


	    
		protected override void OnPreRender(EventArgs e)
		{
			base.OnPreRender(e);
			IExecutionContext executionContext = ExecutionContext.GetCurrent(ClientID);
			ControlUtil.ExecuteOnPreRender(executionContext,Context, Configuration, this.ClientID);
			Bind();
//		    DeclareScriptVariable();
			if (ClientScriptingEnabled)
			{
//				EnableClientScripting();
			    DeclareScriptVariable();
			}

	        this.ToolTip = LocalizedToolTip;
		    

		}

//		private void EnableClientScripting()
//		{
//			ControlUtil.EnsureIdAttribute(this);
//
//
//            JavascriptController.Current.DeclareClass("TextBox");
//            JavascriptController.Current.DeclareObjectWithQuotedParams(ClientVariable, "TextBox", ClientID, Text);
//		}


	    protected override void AddAttributesToRender(HtmlTextWriter writer)
	    {
	        base.AddAttributesToRender(writer);
	        if (ClientScriptingEnabled)
	        {
	            RenderScriptAttributes(writer);
	        }
	        if(this.TextMode==TextBoxMode.Password)
	        {
                writer.AddAttribute(HtmlTextWriterAttribute.Value, Text);
	        }
	    }


	    protected override void OnLoad(EventArgs e)
		{
			base.OnLoad(e);
			IExecutionContext executionContext = ExecutionContext.GetCurrent(ClientID);
			Unbind();								
			ControlUtil.ExecuteOnLoad(executionContext, Context, Configuration, this.ClientID);

            if (Configuration.VisibleBindPath != null)
                this.Visible = true; // To reach the OnPreRender method and analyze visibility in the Bind method
		}
		
		public void OnDataLoad()
		{
			IDictionary executionContext = ExecutionContext.GetCurrent(ClientID);
			ControlUtil.ExecuteOnDataLoad(executionContext, Context, Configuration, this.ClientID);
		}

		protected virtual void Bind()
		{
            this.Visible = Configuration.Visible;
		    
			binder.Bind("Text", Configuration.DataTranslator);
            
		    ToolTip = Configuration.ToolTip;
            ToolTipKey = Configuration.ToolTipKey;
		    binder.Bind("ToolTip");
            binder.Bind("ToolTipKey");
		    
			binder.Bind("Enabled");
            binder.Bind("Visible");
		    		    
            this.Enabled = this.Enabled && Configuration.IsEnabledForPrincipal();
            this.Visible = this.Visible && Configuration.IsVisibleForPrincipal();
            if ((TextMode == TextBoxMode.MultiLine) && Enabled == false)
            {
                Enabled = true;
                ReadOnly = true;
                Attributes.Add("style", "color:gray;");
            }
		}

		protected virtual void Unbind()
		{
			binder.Unbind("Text", Configuration.DataParser);            		    
		    binder.Unbind("ToolTip");
            binder.Unbind("ToolTipKey");
		    binder.Unbind("Enabled");
            binder.Unbind("Visible");
		}

	}
}
